import os
import shutil
from os import path

from cpbox.tool import utils
from cpbox.tool import file
from cpbox.tool import http

URL_DEV = 'https://www-sandbox-317.cp-test.yizhoucp.cn/api/tools'
URL_PRE = 'https://www.cp-pre.yizhoucp.cn/api/tools'
URL_PROD = 'https://config.yizhoucp.cn/api/tools'

PUSH_TYPE_CHANNEL = {
        'huawei': 'huawei',
        'xiaomi': 'xiaomi',
        'meizu': 'meizu',
        'google': 'fcm',
        'oppo': 'oppo',
        'vivo': 'vivo',
        }

DEFAULT_CHANNEL = 'develop'
BUILD_TYPE_DEBUG = 'debug'
BUILD_TYPE_RELEASE = 'release'

APK_BUILD_CMD_DEBUG = 'apkDebug'
APK_BUILD_CMD_RELEASE = 'apkRelease'

class BuildRequest:

    def __init__(self, version_code, version_name, build_type=BUILD_TYPE_DEBUG, channels=DEFAULT_CHANNEL):
        self.version_code = version_code
        self.version_name = version_name
        self.build_type = build_type
        self.channels = channels.split(',')
        self.first_channel = self.channels[0]
        self.push_type = 'xiaomi' if self.first_channel not in PUSH_TYPE_CHANNEL else PUSH_TYPE_CHANNEL[self.first_channel]

    def get_apk_name(self):
        return 'my-right-one_%s_%s_%s.apk' % (self.channel, self.version_code, self.version_name)

    def get_gradlew_cmd(self):
        gradlew_cmd = APK_BUILD_CMD_DEBUG if self.build_type == BUILD_TYPE_DEBUG else APK_BUILD_CMD_RELEASE
        return gradlew_cmd

    # def get_apk_oss_path(self):
    #     remote_path = 'apks/my-right-one/build-v-%s-%s-%s.apk' % (self.version_code, self.version_name, self.env)
    #     return remote_path

class Builder:

    def __init__(self, app, prj_root_dir):
        self.app = app
        self.prj_root_dir = prj_root_dir
        self.build_artifacts_dir = path.join(self.prj_root_dir, 'build-output/artifacts')
        file.ensure_dir(self.build_artifacts_dir)

    def process(self, build_request):
        artifacts_relative_path = path.join('build-output/tmp-apks', build_request.first_channel)
        artifacts_dir = path.join(self.prj_root_dir, artifacts_relative_path)
        shutil.rmtree(artifacts_dir, ignore_errors=True)
        file.ensure_dir(artifacts_dir)

        gradlew_cmd = build_request.get_gradlew_cmd()
        build_cmd = '%s/gradlew clean %s -Dorg.gradle.daemon=true -Pchannels=%s -Poutput=%s' % (self.prj_root_dir, gradlew_cmd, build_request.first_channel, artifacts_relative_path)
        self.app.shell_run(build_cmd)

        mv_cmd = 'mv %s/* %s/' % (artifacts_dir, self.build_artifacts_dir)
        self.app.shell_run(mv_cmd, dry_run=True)

class BuildInfoProvider:

    def __init__(self, app, prj_root_dir, app_key):
        self.app = app
        self.env = app.env
        self.app_key = app_key
        self.prj_root_dir = prj_root_dir
        self._load_build_info()

    def _load_build_info(self):
        local_autogen_properties = utils.load_properties(self.prj_root_dir + '/local-autogen.properties', to_dict=False)
        gradle_properties = utils.load_properties(self.prj_root_dir + '/gradle.properties', to_dict=False)
        version_name = gradle_properties['VERSION_NAME']
        version_name_postfix = local_autogen_properties['VERSION_NAME_POSTFIX']
        self.version_code = local_autogen_properties['VERSION_CODE']
        self.version_name = version_name + '.' + version_name_postfix

    def next_build_num(self):
        # CI use jenkinsBuildNum, local use nextBuildNum of OSS
        next_build_num = os.getenv("BUILD_NUMBER") if os.getenv("BUILD_NUMBER") is not None else self._request_next_build_num()
        return next_build_num

    def _request_next_build_num(self):
        url = self.getBaseUrl() + '/nextBuildNum'
        params = {'app_key': self.app_key}
        ret = http.get(url, params=params)
        num = ret.text
        return num

    def getBaseUrl(self):
        env = self.env
        if env == 'dev':
            return URL_DEV
        elif env == 'pre':
            return URL_PRE
        else:
            return URL_PROD

    def get_last_release_info(self):
        url = self.getBaseUrl() + '/getLastReleaseInfo'
        params = {'app_key': self.app_key, 'env': self.env}
        ret = http.get(url, params=params)
        result = http.fetch_json(url, ret)
        return result['data']

    def update_build_info_file(self, data):
        filename = self.prj_root_dir + '/local-autogen.properties'
        local_autogen_properties = utils.load_properties(filename)
        for key, value in data.items():
            local_autogen_properties[key] = value
        utils.dump_properties(file, local_autogen_properties)
